#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<thread>
#include<mutex>

//懒汉模式
class Singleton
{
public:
	static Singleton* GetInstance()
	{
		if (nullptr == _init)//防止无意义的加锁，因为只需要在第一次实例化对象加锁
		{
			_mtx.lock();		//只需要在创建对象时加锁（写操作），后续直接使用该单例，读操作不需要加锁
			if (nullptr == _init)//保障是第一次实例化对象
			{
				_init = new Singleton;
			}
			_mtx.unlock();
		}
		return _init;
	}
private:
	Singleton() {};//私有隐藏

	Singleton(const Singleton&) = delete;
	Singleton& operator=(const Singleton&) = delete;

private:
	static Singleton* _init;
	static std::mutex _mtx;
};

//程序入口前先初始化静态成员变量
Singleton* Singleton::_init = nullptr;
std::mutex Singleton::_mtx;

int main()
{
	std::thread t1([] {std::cout << Singleton::GetInstance() << std::endl; });
	std::thread t2([] {std::cout << Singleton::GetInstance() << std::endl; });

	t1.join();
	t2.join();

	std::cout << Singleton::GetInstance() << std::endl;
	std::cout << Singleton::GetInstance() << std::endl;
	return 0;
}


//饿汉模式
//class Singleton
//{
//public:
//	static Singleton* GetInstance()
//	{
//		return _init;
//	}
//private:
//	static Singleton* _init;
//
//private:
//	Singleton() {};
//
//	Singleton(const Singleton&) = delete;
//	Singleton& operator=(const Singleton&) = delete;
//};
//
//Singleton* Singleton::_init = new Singleton;
//
//int main()
//{
//	std::thread t1([] {std::cout << Singleton::GetInstance() << std::endl; });
//	std::thread t2([] {std::cout << Singleton::GetInstance() << std::endl; });
//
//	t1.join();
//	t2.join();
//
//	std::cout << Singleton::GetInstance() << std::endl;
//	std::cout << Singleton::GetInstance() << std::endl;
//	return 0;
//}